#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

mod console;
mod network;
mod support;
mod config;
mod logger;
mod utils;
mod remote;
mod remote_version;

use crate::remote::download_remote_log;
use crate::remote_version::fetch_remote_version;

use crate::console::Console;
use crate::network::OnlineChecker;
use crate::network::ServiceInfo;
use imgui::*;
use log::info;
use native_dialog::FileDialog;
use network::create_connection;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use tokio::time::{interval, Duration}; // 添加导入 // Add this line to import OnlineChecker

use std::sync::atomic::{AtomicBool, Ordering};


// Add this line to get the version from Cargo.toml
const VERSION: &str = env!("CARGO_PKG_VERSION");

#[tokio::main]
async fn main() {
    // 在初始化日志之前先读取配置
    let config = config::Config::load();

    // 创建 OnlineChecker 实例
    let mut online_checker = OnlineChecker {
        connection_type: config.network.connection_type.clone(),
        addr: config.network.host.clone(),
        port: config.network.port,
        timeout: Duration::from_secs(10),
        services: HashMap::new(), // Initialize with an empty HashMap or populate it as needed
    };
    // 这里可以添加服务到 online_checker.services
    online_checker.services.insert(
        "orangepi-cli-start.service".to_string(),
        ServiceInfo {
            display_name: "设备服务".to_string(),
            status: "active".to_string(),
        },
    );
    online_checker.services.insert(
        "orangepi-cli-init.service".to_string(),
        ServiceInfo {
            display_name: "系统服务".to_string(),
            status: "activaing".to_string(),
        },
    );
    online_checker.services.insert(
        "orangepi-cli-front.service".to_string(),
        ServiceInfo {
            display_name: "网页服务".to_string(),
            status: "active".to_string(),
        },
    );
    // 使用配置中的日志级别初始化日志系统
    let log_level = logger::parse_log_level(&config.app.log_level);
    logger::init_logger(log_level);

    info!("程序启动");
    info!("日志级别设置为: {}", config.app.log_level);
    info!("应用名称: {}", config.app.app_name);
    info!("pkgtool 路径: {}", config.tool.pkgtool);

    // 获取可执行文件所在目录
    if let Some(exe_dir) = utils::get_executable_dir() {
        info!("可执行文件所在目录: {}", exe_dir.display());
    }

    let dokdo = std::rc::Rc::new(std::cell::RefCell::new(None));
    let dokdo_init = dokdo.clone();

    let mut button_scale = 1.0f32;
    let mut animation_state = 0u8; // 0: 静止, 1: 放大, 2: 缩小
    let mut animation_repeat = 0u8;
    let mut animation_pause = false;
    let mut animation_pause_start = std::time::Instant::now();

    let mut display_pos = [320.0f32, 10.0f32];
    let mut console = Console::new(); // 新增

    let mut auto_scroll = true; // 添加一个布尔变量来存储复选框的状态

    let stop_flag = Arc::new(Mutex::new(false));
    let stop_flag_clone = stop_flag.clone();

    let online_status = Arc::new(Mutex::new(String::from("未知"))); // Add a state variable for online status
    let online_status_clone = online_status.clone();
    let dot_counter = Arc::new(Mutex::new(0)); // Add a counter for dots
    let dot_counter_clone = dot_counter.clone();

    // Modify the app name to include the version number
    let app_name_with_version = format!("{} v{}", config.app.app_name, VERSION);

    let mut last_activity = std::time::Instant::now();

    let service_statuses = Arc::new(Mutex::new(HashMap::new())); // Initialize as Arc<Mutex>
    let service_statuses_clone = service_statuses.clone(); // Clone the Arc for the async task

    let running = Arc::new(AtomicBool::new(true));
    let running_clone = running.clone();
    let config_host = config.network.host.clone();

    let remote_version = Arc::new(Mutex::new(String::from("未知")));
    let remote_version_clone = remote_version.clone();

    // Create a periodic task to check the connection status
    tokio::spawn(async move {
        let mut interval = interval(Duration::from_secs(3)); // Check every 10 seconds
        let mut online_check_counter = 0; // Counter for online checks
                                          // 根据配置选择连接类型
        let connection_type = if config.network.mock_connection {
            "mock"
        } else {
            "tcp"
        };
        // Initial check before entering the loop
        let initial_status = match create_connection(
            connection_type,
            config.network.host.clone(),
            config.network.port,
            Duration::from_secs(5),
        )
        .await
        {
            Ok(_) => "在线".to_string(),
            Err(_) => "离线".to_string(),
        };
        {
            let mut status_lock = online_status_clone.lock().unwrap();
            *status_lock = initial_status;
        }

        while running_clone.load(Ordering::SeqCst) {
            interval.tick().await;
            let status = match create_connection(
                connection_type,
                config.network.host.clone(),
                config.network.port,
                Duration::from_secs(5),
            )
            .await
            {
                Ok(_) => {
                    *dot_counter_clone.lock().unwrap() = 0;
                    online_check_counter += 1;
                    if online_check_counter < 3 {
                        continue;
                    }
                    online_check_counter = 0;
                    "在线".to_string()
                }
                Err(_) => {
                    let mut counter = dot_counter_clone.lock().unwrap();
                    *counter = (*counter + 1) % 4;
                    format!("离线{}", ".".repeat(*counter))
                }
            };

            // 调用 check_services 方法
            let service_statuses_temp: HashMap<String, ServiceInfo> =
                match online_checker.check_services().await {
                    Ok(statuses) => statuses,
                    Err(e) => {
                        info!("Error checking services: {}", e);
                        HashMap::new()
                    }
                };

            let mut statuses_lock = service_statuses_clone.lock().unwrap();
            *statuses_lock = service_statuses_temp;

            let mut status_lock = online_status_clone.lock().unwrap();
            *status_lock = status;
        }
        info!("Background task stopped");
    });

    tokio::spawn(async move {
        if let Some(version) = fetch_remote_version().await {
            let mut version_lock = remote_version_clone.lock().unwrap();
            *version_lock = version;
        }
    });

    // Add this near the top of the main function with other state variables
    let mut selected_com_port = Arc::new(Mutex::new(String::from("COM1")));
    let selected_com_port_clone = selected_com_port.clone();

    support::init_with_startup(
        &app_name_with_version,
        move |ctx, renderer, _| {
            let mut chinese_font_handle = dokdo_init.borrow_mut();

            // this function runs right after the window is created.
            // In your own code, this can be done whenever you have a renderer
            // and a context.
            *chinese_font_handle = Some(ctx.fonts().add_font(&[FontSource::TtfData {
                data: include_bytes!("./resources/方正黑体简体.ttf"),
                size_pixels: support::FONT_SIZE,
                config: Some(FontConfig {
                    // 设置字体范围以包含中文字符
                    glyph_ranges: FontGlyphRanges::chinese_full(),
                    // 其他配置保持默认
                    ..FontConfig::default()
                }),
            }]));

            renderer
                .reload_font_texture(ctx)
                .expect("Failed to reload fonts");
        },


        move |run, ui| {
            // Set running flag to false when window is closed
            if !*run {
                running.store(false, Ordering::SeqCst);
                // 设置停止标志
                if let Ok(mut stop) = stop_flag.lock() {
                    *stop = true;
                }
                info!("Window closing, stopping background tasks...");
            }

            let dokdo = dokdo.borrow().unwrap();

            // 更新控制台输出
            console.update();

            // 原有的 Setting 窗口
            ui.window("Setting")
                .movable(false)
                .position([10.0, 10.0], Condition::FirstUseEver)
                .size([300.0, 300.0], Condition::FirstUseEver)
                .opened(run)
                .build(|| {
                    let _dokdo = ui.push_font(dokdo);

                    ui.text("设置参数");

                    // 显示 Display 窗口的坐标
                    ui.separator();
                    ui.text(format!(
                        "调试信息窗口位置: X={:.1}, Y={:.1}",
                        display_pos[0], display_pos[1]
                    ));
                    // 添加自动滚动复选框
                    ui.checkbox("自动滚动", &mut auto_scroll);

                    if ui.button("导出日志") {
                        let host = config_host.clone();
                        let port = config.network.port;
                        let mut console_clone = console.clone();
                        
                        tokio::spawn(async move {
                            // 下载 /var/log/orangepi-cli.log
                            match download_remote_log(&host, port, "/var/log/orangepi-cli.log", Some("orangepi-cli")).await {
                                Ok(_) => {
                                    console_clone.append_output("日志文件下载成功".to_string());
                                    native_dialog::MessageDialog::new()
                                    .set_type(native_dialog::MessageType::Info)
                                    .set_title("下载orangepi-cli.log成功")
                                    .set_text("日志文件orangepi-cli.log已成功下载")
                                    .show_alert()
                                    .unwrap_or_default();
                                },
                                Err(e) => {
                                    console_clone.append_output(format!("下载日志orangepi-cli.log失败: {}", e));
                                    native_dialog::MessageDialog::new()
                                    .set_type(native_dialog::MessageType::Error)
                                    .set_title("下载失败")
                                    .set_text(&format!("下载日志失败: {}", e))
                                    .show_alert()
                                    .unwrap_or_default();
                                },
                            }
                            
                            // 下载 /logs/app.log
                            match download_remote_log(&host, port, "/logs/app.log", Some("app")).await {
                                Ok(_) => {
                                    console_clone.append_output("应用日志文件下载成功".to_string());
                                    native_dialog::MessageDialog::new()
                                    .set_type(native_dialog::MessageType::Info)
                                    .set_title("下载app.log成功")
                                    .set_text("应用日志文件app.log已成功下载")
                                    .show_alert()
                                    .unwrap_or_default();
                                },
                                Err(e) => {
                                    console_clone.append_output(format!("下载应用日志app.log失败: {}", e));
                                    native_dialog::MessageDialog::new()
                                    .set_type(native_dialog::MessageType::Error)
                                    .set_title("下载失败")
                                    .set_text(&format!("下载应用日志失败: {}", e))
                                    .show_alert()
                                    .unwrap_or_default();
                                },
                            }
                        });
                    }
                    ui.same_line();
                    // 添加三个按钮
                    if ui.button("停止") {
                        let mut stop = stop_flag.lock().unwrap();
                        *stop = true;
                        console.append_output("停止任务!!!".to_string());
                    }
                    ui.same_line();

                    // 检测鼠标活动
                    let window_pos = ui.window_pos();
                    let window_size = ui.window_size();
                    if ui.is_mouse_hovering_rect(
                        window_pos,
                        [
                            window_pos[0] + window_size[0],
                            window_pos[1] + window_size[1],
                        ],
                    ) || ui.is_mouse_clicked(imgui::MouseButton::Left)
                    {
                        last_activity = std::time::Instant::now();
                        button_scale = 1.0;
                        animation_state = 0;
                        animation_repeat = 0;
                        animation_pause = false;
                    }

                    // 检查是否需要开始动画
                    let delta_scale = 0.001;
                    if last_activity.elapsed().as_secs() >= 60 {
                        // 更新动画状态
                        if !animation_pause {
                            match animation_state {
                                0 => {
                                    button_scale = 1.0;
                                    animation_state = 1;
                                }
                                1 => {
                                    button_scale += delta_scale;
                                    if button_scale >= 1.5 {
                                        animation_state = 2;
                                    }
                                }
                                2 => {
                                    button_scale -= delta_scale;
                                    if button_scale <= 0.8 {
                                        animation_state = 1;
                                        animation_repeat += 1;
                                        if animation_repeat >= 2 {
                                            animation_pause = true;
                                            animation_pause_start = std::time::Instant::now();
                                        }
                                    }
                                }
                                _ => {}
                            }
                        } else if animation_pause_start.elapsed().as_secs() >= 2 {
                            animation_pause = false;
                            animation_state = 1;
                            animation_repeat = 0;
                        }
                    }

                    // 检查鼠标是否靠近按钮
                    let mouse_pos = ui.io().mouse_pos;
                    let button_pos = ui.cursor_screen_pos();
                    let button_size = [100.0f32, 20.0f32]; // 估计的按钮大小
                    if mouse_pos[0] >= button_pos[0] - 20.0
                        && mouse_pos[0] <= button_pos[0] + button_size[0] + 20.0
                        && mouse_pos[1] >= button_pos[1] - 20.0
                        && mouse_pos[1] <= button_pos[1] + button_size[1] + 20.0
                    {
                        button_scale = 1.0;
                        animation_state = 0;
                        animation_repeat = 0;
                        animation_pause = false;
                        last_activity = std::time::Instant::now();
                    }

                    ui.set_cursor_pos([
                        ui.cursor_pos()[0] + (100.0 * (1.0 - button_scale)) / 2.0,
                        ui.cursor_pos()[1],
                    ]);
                    let button_width = 100.0 * button_scale;
                    if ui.button_with_size("更新", [button_width, 20.0 * button_scale]) {
                        // 重置 stop_flag 为 false
                        {
                            let mut stop = stop_flag.lock().unwrap();
                            *stop = false;
                        }
                        if let Ok(Some(file_path)) = FileDialog::new()
                            .set_location(&std::env::current_dir().unwrap_or_default())
                            .show_open_single_file()
                        {
                            if let Some(path_str) = file_path.to_str() {
                                info!(
                                    "Executing command: {} update --source {}",
                                    config.tool.pkgtool, path_str
                                );
                                console.execute_command(
                                    &config.tool.pkgtool,
                                    &["update", "--source", path_str],
                                    stop_flag_clone.clone(),
                                );
                            }
                        }
                    }

                    ui.set_cursor_pos([
                        ui.cursor_pos()[0],
                        ui.cursor_pos()[1] - 20.0 * (button_scale - 1.0),
                    ]);

                    // Replace the COM port selection code with this:
                    let com_ports = (1..=30).map(|i| format!("COM{}", i)).collect::<Vec<_>>();
                    let mut current_port = selected_com_port.lock().unwrap().clone();

                    ui.set_next_item_width(100.0);
                    if let Some(combo) = ui.begin_combo("##com_port", &current_port) {
                        for com_port in &com_ports {
                            if &current_port == com_port {
                                ui.set_item_default_focus();
                            }
                            if ui
                                .selectable_config(com_port)
                                .selected(&current_port == com_port)
                                .build()
                            {
                                *selected_com_port.lock().unwrap() = com_port.clone();
                            }
                        }
                        combo.end();
                    }


                    ui.same_line();

                    if ui.button("烧录") {
                        // 重置 stop_flag 为 false
                        {
                            let mut stop = stop_flag.lock().unwrap();
                            *stop = false;
                        }

                        // 执行烧录命令
                        let port = selected_com_port_clone.lock().unwrap().clone();
                        info!("Executing command: {} burn --port {}", config.tool.pkgtool, port);
                        console.execute_command(
                            &config.tool.pkgtool,
                            &["burn", "--port", &port],
                            stop_flag_clone.clone(),
                        );
                    }

                    ui.same_line();
 

                    // Display the online status below the "烧录" button
                    let status = online_status.lock().unwrap();
                    const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0];
                    const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0];
                    if status.starts_with("在线") {
                        let green_color = ui.push_style_color(imgui::StyleColor::Text, GREEN); // Green
                        ui.text(format!("设备状态: {}", *status));
                        green_color.pop();
                    } else {
                        let red_color = ui.push_style_color(imgui::StyleColor::Text, RED); // Red
                        ui.text(format!("设备状态: {}", *status));
                        red_color.pop();
                    }
                    // 打印每个服务的状态
                    let statuses_lock = service_statuses.lock().unwrap(); // Lock the mutex to access the data
                    for (_service_key, service_info) in statuses_lock.iter() {
                        // info!("{} 状态: {}", service_name, status);
                        // Add this line to display service status in the UI
                        ui.text(format!(
                            "{} 状态: {}",
                            service_info.display_name, service_info.status
                        ));
                    }

                    let version = remote_version.lock().unwrap();
                    ui.text(format!("设备应用版本号: {}", *version));

                    _dokdo.pop();
                });

            // Display 窗口
            if let Some(window) = ui
                .window("Display")
                .size([640.0, 480.0], Condition::FirstUseEver)
                .position(display_pos, Condition::FirstUseEver)
                .begin()
            {
                let _dokdo = ui.push_font(dokdo);
                ui.text("调试信息");
                ui.separator();

                // 显示控制台输出
                let output = console.get_output();
                for line in output {
                    ui.text(line);
                }

                // 自动滚动到末尾
                if auto_scroll {
                    ui.set_scroll_here_y_with_ratio(1.0);
                }

                _dokdo.pop();

                // 更新窗口位置
                display_pos = ui.window_pos();

                window.end();
            }
        },
    );
}
